home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NetNews Offline 2
/
NetNews Offline Volume 2.iso
/
news
/
comp
/
std
/
c
/
618
< prev
next >
Wrap
Text File
|
1996-08-06
|
3KB
|
89 lines
Newsgroups: comp.std.c
Path: nntp.coast.net!torn!sq!msb
From: msb@sq.com (Mark Brader)
Subject: Re: Restrictions on qsort compare function?
Message-ID: <1996Mar21.113301.2622@sq.com>
Organization: SoftQuad Inc., Toronto, Canada
References: <4iokop$h4p@lyra.csx.cam.ac.uk> <4iqjar$2m9@usenet.pa.dec.com>
Date: Thu, 21 Mar 1996 11:33:01 GMT
> > Are there any limitations on what the sort function
It's better to call it a comparison function; qsort() is the sort function.
> > passed over to qsort can do or return?
The standard states
# The function shall return an integer less than, equal to, or greater
# than zero if the first argument is considered to be respectively
# less than, equal to, or greater than the second.
In other words, it must yield an ordering of the possible data values.
This is only the case if
1. It is a pure function:
repeated calls to compar(x,y) yield a result having the
same sign each time
2. It is antisymmetric (I think that's the right word):
if compar(x,y) < 0, then compar(y,x) > 0
if compar(x,y) == 0, then compar(y,x) == 0
if compar(x,y) > 0, then compar(y,x) < 0
3. If is transitive:
if compar(x,y) > 0 && compar(y,z) > 0, then compar(x,z) > 0
> > I know it's meant to return < 0, 0 or > 0 for the various compare
> > operations, but which you return is purely up to your own comparison
> > system.
Yes, so long as it obeys *some* comparison system.
> > On tracking down a bug in some old code I noticed that we had the
> > compare function returning something like "a > b" instead of "b - a".
>
> Just one sentence earlier, you gave the exact reason why
> it doesn't matter if you do "a > b" instead of "a - b".
Of course it matters. With this function, if compar(x,y) > 0, then
compar(y,x) == 0. This is not antisymmetric.
it is not a proper comparison function and the behavior is undefined.
> (Actually it can matter: if "a - b" would overflow then doing "a > b"
> will fix it instead of yielding undefined behavior :-)
Well, "a - b" is indeed unsuitable in general due to potential overflow.
If the numbers being subtracted are floating-point or are signed integers,
then arithmetic overflow may occur, causing undefined behavior. It might
be safe if they are unsigned integers, but then, unless they are narrower
than int, you run into implementation-defined behavior on converting the
result of the subtraction to the int that the function returns.
But changing to "a > b", as noted, does not fix it. If simple arithmetic
comparison is what you want, then you should use something like:
(a > b)? 1: (a < b)? -1: 0
Terser equivalents, but probably considered less clear by most people, are:
(a < b)? -1: (a > b)
and
(a > b) - (a < b)
> > My understanding of this is that qsort() ought to be able to handle any
> > [comparison] function, even if it's something as dumb as (rand()%3)-1.
>
> That would not be a [comparison] function (it might even assert that a < b
> and b < c and c < a).
Right. In fact, it would not necessarily obey any of the three properties
mentioned above, so the behavior of qsort() would be undefined.
--
Mark Brader At any rate, C++ != C. Actually, the value of the
msb@sq.com expression "C++ != C" is [undefined].
SoftQuad Inc., Toronto -- Peter da Silva
My text in this article is in the public domain.